#include "BezierCurve.h"
#include <vector>
#include <cmath>
#include <sstream>
#include "Function.hpp"
using namespace std;
const double pi = acos(-1.);

class F: public Function {
public:
    dot operator() (double t) const {
        dot dot_t;
        if(t>=0 && t<=0.5){
            dot_t.x = sqrt(3) * sin(2 * pi * t);
            dot_t.y = (2.0 / 3.0) * (pow(3, 0.25) * sqrt(sin(2 * pi * t)) - sqrt(3) * cos(2 * pi * t));
        }
        else{
            dot_t.x = sqrt(3) * sin(2 * pi * t);
            dot_t.y = (2.0 / 3.0) * (pow(3, 0.25) * sqrt(-sin(2 * pi * t)) - sqrt(3) * cos(2 * pi * t));
        }
        return dot_t;
    }
    dot derivative(double t) const {
        dot dot_t;
        if(t>=0 && t<=0.5){
            dot_t.x = 2 * pi * sqrt(3) * cos(2 * pi * t);
            dot_t.y = (2.0 / 3.0) * ((pow(3, 0.25) * pi * cos(2 * pi * t)) / sqrt(sin(2 * pi * t)) + sqrt(3) * 2 * pi * sin(2 * pi * t));
        }
        else{
            dot_t.x = 2 * pi * sqrt(3) * cos(2 * pi * t);
            dot_t.y = (2.0 / 3.0) * ((-pow(3, 0.25) * pi * cos(2 * pi * t)) / sqrt(-sin(2 * pi * t)) + sqrt(3) * 2 * pi * sin(2 * pi * t));
        }
        return dot_t;
    }
};

int main() {
    vector<dot> points;
    int m_values[] = {10, 40, 160};

    for (int m : m_values) {
        stringstream title_stream;
        title_stream << "Bezier Curve Approximation (m = " << m << ")";
        plt::title(title_stream.str());
        approximateWithBezierCurves(F(), m, 0, 1);
    }

    return 0;
}